<script setup>
import { ref, reactive } from 'vue'
import mqtt from 'mqtt'

const qosList = [0, 1, 2]
// 定义连接参数的对象
const connectInfo = ref({
    protocol: 'ws',
    host: '192.168.1.131',
    port: '8083',
    clientId: 'emqx_vue_client_' + Math.random().toString().substring(2, 8),
    username: 'zhangsan',
    password: '123456'
})

const clientInitData = ref({
    connected: false
})
const client = ref({})
const createConnection = () => {
    const { protocol, host, port, ...options } = connectInfo.value
    const connectUrl = `${protocol}://${host}:${port}/mqtt`
    client.value = mqtt.connect(connectUrl, options)
    clientInitData.value.connected = true
    console.log('连接建立成功了')
}

const closeConnection = () => {
    client.value.end(false, () => {
        clientInitData.value.connected = false
        console.log('连接关闭成功了')
    })

}

const subscriptionInfo = ref({
    topic: '',
    qos: 0
})

const receivedMessages = ref({})
const subscriptionInitData = ref({
    subscription: false
})
const subscriptionTopicHandler = () => {
    const { topic, qos } = subscriptionInfo.value
    client.value.subscribe(topic, { qos }, (error, res) => {
        if (error) {
            console.log('主题订阅失败了', error)
            return
        }
        subscriptionInitData.value.subscription = true
        //给链接对象注册一个接收消息的事件
        client.value.on('message', (topic, message) => {
            console.log('接收到消息：', topic, message)
            receivedMessages.value = topic + '--->' + message
        })
    })
}

const unSubscriptionTopicHandler = () => {
    const { topic, qos } = subscriptionInfo.value
    client.value.unsubscribe(topic, { qos }, (error, res) => {
        if (error) {
            console.log('主题取消订阅失败了', error)
            return
        }
        subscriptionInitData.value.subscription = false
    })
}

const publishInfo = ref({
    topic: '',
    qos: 0,
    payload: ''
})

const doPublish = () => {
    const { topic, qos, payload } = publishInfo.value
    client.value.publish(topic, payload, { qos }, (error, res) => {
        if (error) {
            console.log('发送消息失败了', error)
            return
        }
    })
}

</script>

<template>
    <el-card>
        <h4>配置信息</h4>
        <el-form label-width="120px">
            <el-row :gutter="20">
                <el-col :span="8">
                    <el-form-item label="协议" prop="protocol">
                        <el-select v-model="connectInfo.protocol">
                            <el-option label="ws://" value="ws"></el-option>
                            <el-option label="wss://" value="wss"></el-option>
                        </el-select>
                    </el-form-item>
                </el-col>
                <el-col :span="8">
                    <el-form-item label="主机地址" prop="host">
                        <el-input v-model="connectInfo.host"></el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="8">
                    <el-form-item label="端口" prop="port">
                        <el-input v-model="connectInfo.port"></el-input>
                    </el-form-item>
                </el-col>
            </el-row>

            <el-row :gutter="20">
                <el-col :span="8">
                    <el-form-item label="clientId" prop="clientId">
                        <el-input v-model="connectInfo.clientId"></el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="8">
                    <el-form-item label="用户名" prop="username">
                        <el-input v-model="connectInfo.username"></el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="8">
                    <el-form-item label="密码" prop="password">
                        <el-input v-model="connectInfo.password"></el-input>
                    </el-form-item>
                </el-col>
            </el-row>

            <el-row :gutter="20">
                <el-col :span="24">
                    <el-button type="primary" :disabled="clientInitData.connected"
                        @click="createConnection">建立连接</el-button>
                    <el-button type="danger" :disabled="!clientInitData.connected"
                        @click="closeConnection">断开连接</el-button>
                </el-col>
            </el-row>
        </el-form>
    </el-card>

    <el-card>
        <h4>订阅主题</h4>
        <el-form label-width="120px">
            <el-row :gutter="20">
                <el-col :span="8">
                    <el-form-item label="Topic" prop="topic">
                        <el-input v-model="subscriptionInfo.topic"></el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="8">
                    <el-form-item label="Qos" prop="qos">
                        <el-select v-model="subscriptionInfo.qos">
                            <el-option v-for="item in qosList" :label="item" :value="item"></el-option>
                        </el-select>
                    </el-form-item>
                </el-col>
                <el-col :span="8">
                    <el-button type="primary" :disabled="subscriptionInitData.subscription"
                        @click="subscriptionTopicHandler">订阅主题</el-button>
                    <el-button type="warning" :disabled="!subscriptionInitData.subscription"
                        @click="unSubscriptionTopicHandler">取消订阅</el-button>
                </el-col>
            </el-row>
        </el-form>
    </el-card>

    <el-card>
        <h4>发布消息</h4>
        <el-form label-width="120px">
            <el-row :gutter="20">
                <el-col :span="8">
                    <el-form-item label="Topic" prop="topic">
                        <el-input v-model="publishInfo.topic"></el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="8">
                    <el-form-item label="Qos" prop="field5">
                        <el-select v-model="publishInfo.qos">
                            <el-option v-for="item in qosList" :label="item" :value="item"></el-option>
                        </el-select>
                    </el-form-item>
                </el-col>
                <el-col :span="8">
                    <el-form-item label="Payload" prop="payload">
                        <el-input v-model="publishInfo.payload"></el-input>
                    </el-form-item>
                </el-col>
            </el-row>

            <el-row :gutter="20">
                <el-col :span="24">
                    <el-button type="primary" @click="doPublish">发布消息</el-button>
                </el-col>
            </el-row>
        </el-form>
    </el-card>

    <el-card>
        <h4>接收到的消息</h4>
        <el-form>
            <el-input v-model="receivedMessages" style="width: 98%" :rows="5" type="textarea" />
        </el-form>
    </el-card>

</template>

<style scoped>
.el-row {
    margin-bottom: 20px;
}

.el-col {
    border-radius: 4px;
}
</style>